# -*- coding: utf-8 -*-
# Script Python que actúa como wrapper para ejecución en entorno wxPython
# de scripts Python.

## vipera, un diseñador de aplicaciones para Python
##     Copyright (C) 2011 Ángel Luis García García
##
##    This program is free software: you can redistribute it and/or modify
##    it under the terms of the GNU General Public License as published by
##    the Free Software Foundation, either version 3 of the License, or
##    (at your option) any later version.
##
##    This program is distributed in the hope that it will be useful,
##    but WITHOUT ANY WARRANTY; without even the implied warranty of
##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##    GNU General Public License for more details.
##
##    You should have received a copy of the GNU General Public License
##    along with this program.  If not, see <http://www.gnu.org/licenses/>.

import wx

import sys
import codecs

class lanzadera(object):
    '''Clase lanzadera de código Python.'''
    def __init__(self, fichero_python, 
                 fichero_salida, fichero_errores,
                 salida_fich):
        '''Constructor de clase'''
        self.__fichero = fichero_python
        self.__salida = fichero_salida
        self.__errores = fichero_errores
        self.__app = wx.PySimpleApp()
        self.__salida_fich = salida_fich

    def _raw_input_wx(self, param):
        '''Creamos un diálogo de introducción de datos.'''
        dialogo = wx.TextEntryDialog(None, param, "raw_input")
        dialogo.Show()
        if dialogo.ShowModal() == wx.ID_OK:
            ret = dialogo.GetValue()
        else:
            ret = None
        # Destruimos el diálogo.
        dialogo.Destroy()
        # Y devolvemos valor.
        return ret

    def _input_wx(self, param):
        '''Creamos un diálogo de introducción de datos.'''
        dialogo = wx.TextEntryDialog(None, param, "input")
        dialogo.Show()
        if dialogo.ShowModal() == wx.ID_OK:
            ret = eval(dialogo.GetValue())
        else:
            ret = None
        # Destruimos el diálogo.
        dialogo.Destroy()
        # Y devolvemos valor.
        return ret

    def _codigo(self):
        '''Obtenemos fichero código fuente Python.'''
        f = codecs.open(self.__fichero,'r','utf-8')
        codigo = f.read()
        f.close()
        # Devolvemos código.
        return codigo

    def _ejecutar_codigo(self, codigo = None, opcion = 1):
        '''Ejecución de código.'''
        if self.__salida_fich:
            # Creamos ficheros de salida y errores.
            fs = codecs.open(self.__salida,'w','utf-8')
            fe = codecs.open(self.__errores,'w','utf-8')
            # Guardamos entrada y salida.
            aux_stdout = sys.stdout
            aux_stderr = sys.stderr
            # Redireccionamos salida y error.
            sys.stdout = fs
            sys.stderr = fe
        # #########################################################
        # Ejecutamos código... cuando se ejecute raw_input ó input,
        # se ejecutará nuestra versión wx.
        # #########################################################
        if opcion == 0:
            exec codigo in {'raw_input':self._raw_input_wx,
                            'input':self._input_wx} 
        if opcion == 1:
            execfile(self.__fichero, {'raw_input':self._raw_input_wx,
                                      'input':self._input_wx}) 
        # #########################################################
        if self.__salida_fich:
            # Cerramos ficheros.
            fs.close()
            fe.close()
            # Guardamos entrada y salida.
            sys.stdout = aux_stdout 
            sys.stderr = aux_stderr

    def lanzar(self, por_defecto = 'desde_fichero'):
        '''Método de lanzamiento de código Python.'''
        if por_defecto == 'desde_fichero':
            self._ejecutar_codigo()
        if por_defecto == 'desde_cadena':
            codigo = self._codigo()
            self._ejecutar_codigo(codigo,0)

if len(sys.argv) == 5:
    # Recogemos datos.
    fichero_python = sys.argv[1]
    fichero_salida = sys.argv[2]
    fichero_errores = sys.argv[3]
    flag_salida = sys.argv[4]
    # Codificamos flag salida.
    if flag_salida == '0': flag_salida = False
    else: flag_salida = True
    # Lanzamos el código.
    script_ejecucion = lanzadera(fichero_python,
                                 fichero_salida,
                                 fichero_errores,
                                 flag_salida)
    script_ejecucion.lanzar()